home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / CardLayout.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  14.2 KB  |  462 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)CardLayout.java    1.27 98/09/15
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt;
  16.  
  17. import java.util.Hashtable;
  18. import java.util.Enumeration;
  19.  
  20. /**
  21.  * A <code>CardLayout</code> object is a layout manager for a
  22.  * container. It treats each component in the container as a card.
  23.  * Only one card is visible at a time, and the container acts as
  24.  * a stack of cards. The first component added to a 
  25.  * <code>CardLayout</code> object is the visible component when the 
  26.  * container is first displayed.
  27.  * <p>
  28.  * The ordering of cards is determined by the container's own internal
  29.  * ordering of its component objects. <code>CardLayout</code>
  30.  * defines a set of methods that allow an application to flip
  31.  * through these cards sequentially, or to show a specified card.
  32.  * The {@link CardLayou#addLayoutComponent}
  33.  * method can be used to associate a string identifier with a given card
  34.  * for fast random access.
  35.  *
  36.  * @version     1.27 09/15/98
  37.  * @author     Arthur van Hoff
  38.  * @see         java.awt.Container
  39.  * @since       JDK1.0
  40.  */
  41.  
  42. public class CardLayout implements LayoutManager2,
  43.                    java.io.Serializable {
  44.     /*
  45.     * This creates a hashtable, where any non-null object
  46.     * can be used as a key or value.
  47.     * @serial
  48.     * @see java.util.HashTable
  49.     */
  50.     Hashtable tab = new Hashtable();
  51.  
  52.     /*
  53.     * A cards horizontal Layout gap (inset). It specifies
  54.     * the space between the left and right edges of a 
  55.     * container and the current component.
  56.     * This should be a non negative Integer.
  57.     * @serial
  58.     * @see getHgap()
  59.     * @see setHgap()
  60.     */
  61.     int hgap;
  62.  
  63.     /*
  64.     * A cards vertical Layout gap (inset). It specifies
  65.     * the space between the top and bottom edges of a 
  66.     * container and the current component.
  67.     * This should be a non negative Integer.
  68.     * @serial
  69.     * @see getVgap()
  70.     * @see setVgap()
  71.     */
  72.     int vgap;
  73.  
  74.     /**
  75.      * Creates a new card layout with gaps of size zero.
  76.      */
  77.     public CardLayout() {
  78.     this(0, 0);
  79.     }
  80.  
  81.     /**
  82.      * Creates a new card layout with the specified horizontal and
  83.      * vertical gaps. The horizontal gaps are placed at the left and
  84.      * right edges. The vertical gaps are placed at the top and bottom
  85.      * edges.
  86.      * @param     hgap   the horizontal gap.
  87.      * @param     vgap   the vertical gap.
  88.      */
  89.     public CardLayout(int hgap, int vgap) {
  90.     this.hgap = hgap;
  91.     this.vgap = vgap;
  92.     }
  93.  
  94.     /**
  95.      * Gets the horizontal gap between components.
  96.      * @return    the horizontal gap between components.
  97.      * @see       java.awt.CardLayout#setHgap(int)
  98.      * @see       java.awt.CardLayout#getVgap()
  99.      * @since     JDK1.1
  100.      */
  101.     public int getHgap() {
  102.     return hgap;
  103.     }
  104.  
  105.     /**
  106.      * Sets the horizontal gap between components.
  107.      * @param hgap the horizontal gap between components.
  108.      * @see       java.awt.CardLayout#getHgap()
  109.      * @see       java.awt.CardLayout#setVgap(int)
  110.      * @since     JDK1.1
  111.      */
  112.     public void setHgap(int hgap) {
  113.     this.hgap = hgap;
  114.     }
  115.  
  116.     /**
  117.      * Gets the vertical gap between components.
  118.      * @return the vertical gap between components.
  119.      * @see       java.awt.CardLayout#setVgap(int)
  120.      * @see       java.awt.CardLayout#getHgap()
  121.      */
  122.     public int getVgap() {
  123.     return vgap;
  124.     }
  125.  
  126.     /**
  127.      * Sets the vertical gap between components.
  128.      * @param     vgap the vertical gap between components.
  129.      * @see       java.awt.CardLayout#getVgap()
  130.      * @see       java.awt.CardLayout#setHgap(int)
  131.      * @since     JDK1.1
  132.      */
  133.     public void setVgap(int vgap) {
  134.     this.vgap = vgap;
  135.     }
  136.  
  137.     /**
  138.      * Adds the specified component to this card layout's internal
  139.      * table of names. The object specified by <code>constraints</code>
  140.      * must be a string. The card layout stores this string as a key-value
  141.      * pair that can be used for random access to a particular card.
  142.      * By calling the <code>show</code> method, an application can
  143.      * display the component with the specified name.
  144.      * @param     comp          the component to be added.
  145.      * @param     constraints   a tag that identifies a particular
  146.      *                                        card in the layout.
  147.      * @see       java.awt.CardLayout#show(java.awt.Container, java.lang.String)
  148.      * @exception  IllegalArgumentException  if the constraint is not a string.
  149.      */
  150.     public void addLayoutComponent(Component comp, Object constraints) {
  151.       synchronized (comp.getTreeLock()) {
  152.     if (constraints instanceof String) {
  153.         addLayoutComponent((String)constraints, comp);
  154.     } else {
  155.         throw new IllegalArgumentException("cannot add to layout: constraint must be a string");
  156.     }
  157.       }
  158.     }
  159.  
  160.     /**
  161.      * @deprecated   replaced by
  162.      *      <code>addLayoutComponent(Component, Object)</code>.
  163.      */
  164.     public void addLayoutComponent(String name, Component comp) {
  165.       synchronized (comp.getTreeLock()) {
  166.     if (tab.size() > 0) {
  167.         comp.hide();
  168.     }
  169.     tab.put(name, comp);
  170.       }
  171.     }
  172.  
  173.     /**
  174.      * Removes the specified component from the layout.
  175.      * @param   comp   the component to be removed.
  176.      * @see     java.awt.Container#remove(java.awt.Component)
  177.      * @see     java.awt.Container#removeAll()
  178.      */
  179.     public void removeLayoutComponent(Component comp) {
  180.       synchronized (comp.getTreeLock()) {
  181.     for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) {
  182.         String key = (String)e.nextElement();
  183.         if (tab.get(key) == comp) {
  184.         tab.remove(key);
  185.         return;
  186.         }
  187.     }
  188.       }
  189.     }
  190.  
  191.     /**
  192.      * Determines the preferred size of the container argument using
  193.      * this card layout.
  194.      * @param   parent the name of the parent container.
  195.      * @return  the preferred dimensions to lay out the subcomponents
  196.      *                of the specified container.
  197.      * @see     java.awt.Container#getPreferredSize
  198.      * @see     java.awt.CardLayout#minimumLayoutSize
  199.      */
  200.     public Dimension preferredLayoutSize(Container parent) {
  201.       synchronized (parent.getTreeLock()) {
  202.     Insets insets = parent.getInsets();
  203.     int ncomponents = parent.getComponentCount();
  204.     int w = 0;
  205.     int h = 0;
  206.  
  207.     for (int i = 0 ; i < ncomponents ; i++) {
  208.         Component comp = parent.getComponent(i);
  209.         Dimension d = comp.getPreferredSize();
  210.         if (d.width > w) {
  211.         w = d.width;
  212.         }
  213.         if (d.height > h) {
  214.         h = d.height;
  215.         }
  216.     }
  217.     return new Dimension(insets.left + insets.right + w + hgap*2,
  218.                  insets.top + insets.bottom + h + vgap*2);
  219.       }
  220.     }
  221.  
  222.     /**
  223.      * Calculates the minimum size for the specified panel.
  224.      * @param     parent the name of the parent container
  225.      *                in which to do the layout.
  226.      * @return    the minimum dimensions required to lay out the
  227.      *                subcomponents of the specified container.
  228.      * @see       java.awt.Container#doLayout
  229.      * @see       java.awt.CardLayout#preferredLayoutSize
  230.      */
  231.     public Dimension minimumLayoutSize(Container parent) {
  232.       synchronized (parent.getTreeLock()) {
  233.     Insets insets = parent.getInsets();
  234.     int ncomponents = parent.getComponentCount();
  235.     int w = 0;
  236.     int h = 0;
  237.  
  238.     for (int i = 0 ; i < ncomponents ; i++) {
  239.         Component comp = parent.getComponent(i);
  240.         Dimension d = comp.getMinimumSize();
  241.         if (d.width > w) {
  242.         w = d.width;
  243.         }
  244.         if (d.height > h) {
  245.         h = d.height;
  246.         }
  247.     }
  248.     return new Dimension(insets.left + insets.right + w + hgap*2,
  249.                  insets.top + insets.bottom + h + vgap*2);
  250.       }
  251.     }
  252.  
  253.     /**
  254.      * Returns the maximum dimensions for this layout given the components
  255.      * in the specified target container.
  256.      * @param target the component which needs to be laid out
  257.      * @see Container
  258.      * @see #minimumLayoutSize
  259.      * @see #preferredLayoutSize
  260.      */
  261.     public Dimension maximumLayoutSize(Container target) {
  262.     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  263.     }
  264.  
  265.     /**
  266.      * Returns the alignment along the x axis.  This specifies how
  267.      * the component would like to be aligned relative to other
  268.      * components.  The value should be a number between 0 and 1
  269.      * where 0 represents alignment along the origin, 1 is aligned
  270.      * the furthest away from the origin, 0.5 is centered, etc.
  271.      */
  272.     public float getLayoutAlignmentX(Container parent) {
  273.     return 0.5f;
  274.     }
  275.  
  276.     /**
  277.      * Returns the alignment along the y axis.  This specifies how
  278.      * the component would like to be aligned relative to other
  279.      * components.  The value should be a number between 0 and 1
  280.      * where 0 represents alignment along the origin, 1 is aligned
  281.      * the furthest away from the origin, 0.5 is centered, etc.
  282.      */
  283.     public float getLayoutAlignmentY(Container parent) {
  284.     return 0.5f;
  285.     }
  286.  
  287.     /**
  288.      * Invalidates the layout, indicating that if the layout manager
  289.      * has cached information it should be discarded.
  290.      */
  291.     public void invalidateLayout(Container target) {
  292.     }
  293.  
  294.     /**
  295.      * Lays out the specified container using this card layout.
  296.      * <p>
  297.      * Each component in the <code>parent</code> container is reshaped
  298.      * to be the size of the container, minus space for surrounding
  299.      * insets, horizontal gaps, and vertical gaps.
  300.      *
  301.      * @param     parent the name of the parent container
  302.      *                             in which to do the layout.
  303.      * @see       java.awt.Container#doLayout
  304.      */
  305.     public void layoutContainer(Container parent) {
  306.       synchronized (parent.getTreeLock()) {
  307.     Insets insets = parent.getInsets();
  308.     int ncomponents = parent.getComponentCount();
  309.     for (int i = 0 ; i < ncomponents ; i++) {
  310.         Component comp = parent.getComponent(i);
  311.         if (comp.visible) {
  312.         comp.setBounds(hgap + insets.left, vgap + insets.top,
  313.                    parent.width - (hgap*2 + insets.left + insets.right),
  314.                    parent.height - (vgap*2 + insets.top + insets.bottom));
  315.         }
  316.     }
  317.       }
  318.     }
  319.  
  320.     /**
  321.      * Make sure that the Container really has a CardLayout installed.
  322.      * Otherwise havoc can ensue!
  323.      */
  324.     void checkLayout(Container parent) {
  325.     if (parent.getLayout() != this) {
  326.         throw new IllegalArgumentException("wrong parent for CardLayout");
  327.     }
  328.     }
  329.  
  330.     /**
  331.      * Flips to the first card of the container.
  332.      * @param     parent   the name of the parent container
  333.      *                          in which to do the layout.
  334.      * @see       java.awt.CardLayout#last
  335.      */
  336.     public void first(Container parent) {
  337.     synchronized (parent.getTreeLock()) {
  338.         checkLayout(parent);
  339.         int ncomponents = parent.getComponentCount();
  340.         for (int i = 0 ; i < ncomponents ; i++) {
  341.         Component comp = parent.getComponent(i);
  342.         if (comp.visible) {
  343.             comp.hide();
  344.             comp = parent.getComponent(0);
  345.             comp.show();
  346.             parent.validate();
  347.             return;
  348.         }
  349.         }
  350.     }
  351.     }
  352.  
  353.     /**
  354.      * Flips to the next card of the specified container. If the
  355.      * currently visible card is the last one, this method flips to the
  356.      * first card in the layout.
  357.      * @param     parent   the name of the parent container
  358.      *                          in which to do the layout.
  359.      * @see       java.awt.CardLayout#previous
  360.      */
  361.     public void next(Container parent) {
  362.     synchronized (parent.getTreeLock()) {
  363.         checkLayout(parent);
  364.         int ncomponents = parent.getComponentCount();
  365.         for (int i = 0 ; i < ncomponents ; i++) {
  366.         Component comp = parent.getComponent(i);
  367.         if (comp.visible) {
  368.             comp.hide();
  369.             comp = parent.getComponent((i + 1 < ncomponents) ? i+1 : 0);
  370.             comp.show();
  371.             parent.validate();
  372.             return;
  373.         }
  374.         }
  375.     }
  376.     }
  377.  
  378.     /**
  379.      * Flips to the previous card of the specified container. If the
  380.      * currently visible card is the first one, this method flips to the
  381.      * last card in the layout.
  382.      * @param     parent   the name of the parent container
  383.      *                          in which to do the layout.
  384.      * @see       java.awt.CardLayout#next
  385.      */
  386.     public void previous(Container parent) {
  387.     synchronized (parent.getTreeLock()) {
  388.         checkLayout(parent);
  389.         int ncomponents = parent.getComponentCount();
  390.         for (int i = 0 ; i < ncomponents ; i++) {
  391.         Component comp = parent.getComponent(i);
  392.         if (comp.visible) {
  393.             comp.hide();
  394.             comp = parent.getComponent((i > 0) ? i-1 : ncomponents-1);
  395.             comp.show();
  396.             parent.validate();
  397.             return;
  398.         }
  399.         }
  400.     }
  401.     }
  402.  
  403.     /**
  404.      * Flips to the last card of the container.
  405.      * @param     parent   the name of the parent container
  406.      *                          in which to do the layout.
  407.      * @see       java.awt.CardLayout#first
  408.      */
  409.     public void last(Container parent) {
  410.     synchronized (parent.getTreeLock()) {
  411.         checkLayout(parent);
  412.         int ncomponents = parent.getComponentCount();
  413.         for (int i = 0 ; i < ncomponents ; i++) {
  414.         Component comp = parent.getComponent(i);
  415.         if (comp.visible) {
  416.             comp.hide();
  417.             comp = parent.getComponent(ncomponents - 1);
  418.             comp.show();
  419.             parent.validate();
  420.             return;
  421.         }
  422.         }
  423.     }
  424.     }
  425.  
  426.     /**
  427.      * Flips to the component that was added to this layout with the
  428.      * specified <code>name</code>, using <code>addLayoutComponent</code>.
  429.      * If no such component exists, then nothing happens.
  430.      * @param     parent   the name of the parent container
  431.      *                     in which to do the layout.
  432.      * @param     name     the component name.
  433.      * @see       java.awt.CardLayout#addLayoutComponent(java.awt.Component, java.lang.Object)
  434.      */
  435.     public void show(Container parent, String name) {
  436.     synchronized (parent.getTreeLock()) {
  437.         checkLayout(parent);
  438.         Component next = (Component)tab.get(name);
  439.         if ((next != null) && !next.visible){
  440.         int ncomponents = parent.getComponentCount();
  441.         for (int i = 0 ; i < ncomponents ; i++) {
  442.             Component comp = parent.getComponent(i);
  443.             if (comp.visible) {
  444.             comp.hide();
  445.             break;
  446.             }
  447.         }
  448.         next.show();
  449.         parent.validate();
  450.         }
  451.     }
  452.     }
  453.  
  454.     /**
  455.      * Returns a string representation of the state of this card layout.
  456.      * @return    a string representation of this card layout.
  457.      */
  458.     public String toString() {
  459.     return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
  460.     }
  461. }
  462.